# -*- coding: utf-8 -*-

import  tornado
import tornado.ioloop
from tornado.options import define, options
import tornado.web
from WXBizMsgCrypt import WXBizMsgCrypt
import urllib
import xml.etree.cElementTree as ET
import datetime
import requests
import xmlrpclib
#import  psycopg2


SToken = "tdyW42QdWKoiuNwGjh"
sEncodingAESKey = "qRmvrrBE7IE9rB1g1uJkTpOPnErttEmSPrZ9yBs2HCG"

sCorpID = "wx2b6a644956aea8d6"
policy_SToken = "policy"
policy_sEncodingAESKey = "pUmxePGpBIx5HP3KMpSNk6EupYSuoe6QyX0PnDaWztt"

message_SToken = "message"
message_sEncodingAESKey = "BULIWEzbQRm3OyzYO2OlsLjWw50jRINgA8dbr64HxqY"

WEATHER_URL = "http://apix.sinaapp.com/weather/?appkey=trialuser&city=%s"
GET_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s"
it_key = "LB437Fd5jpguFMfNV2wecwZ-5UBTlulbSLW78Qmt1hXnUD3RG8tTn0LIZO8mYwJz"

odoo_common_url = "http://114.215.192.144:8069/xmlrpc/common"
odoo_object_url = "http://114.215.192.144:8069/xmlrpc/2/object"
odoo_user = "admin"
odoo_pwd = "admin"
odoo_db = "policy"

define("pgsql_port",default="3012",help="postgresql port")
define("pgsql_host", default="10.242.183.213", help="database host")
define("pgsql_database", default="weixin", help="database name")
define("pgsql_user", default="pgtest012", help="database user")
define("pgsql_password", default="pg94012", help="database password")

ERROS = {
    '-1':"weixin code has been exists",
    '0':'username has been exists',
    '1':'bind success',
}

def get_user_info(openid):
    conn = psycopg2.connect(database=options.pgsql_database,user=options.pgsql_user,password=options.pgsql_password,
                            host=options.pgsql_host,port=options.pgsql_port)
    cur = conn.cursor()
    cur.execute("select * from users where openid='%s'"%openid)
    item= cur.fetchone()
    conn.commit()
    cur.close()
    conn.close()
    return item

def add_user(item):
    conn = psycopg2.connect(database=options.pgsql_database,user=options.pgsql_user,password=options.pgsql_password,
                            host=options.pgsql_host,port=options.pgsql_port)
    cur = conn.cursor()
    cur.execute("select * from users where openid='%s'"%item['openid'])
    if cur.fetchone():
        return -1
    cur.execute("select * from users where username = '%s' "%item['username'])
    if cur.fetchone():
        return 0
    cur.execute("insert into users(openid,username,password) values ('%s','%s','%s')" %(item['openid'],item['username'],item['password']))
    conn.commit()
    cur.close()
    conn.close()
    return 1

def connect(url,db,username,pwd):
    sock = xmlrpclib.ServerProxy(url)
    uid = sock.login(db,username,pwd)
    return uid

def get_access_token(handler):
        access_token = handler.get_cookie("access_token")
        print "cookie access_token is %s " % access_token
        if not access_token:
            res = requests.get(GET_TOKEN_URL%(sCorpID,it_key))
            access_token = res.json()["access_token"]
            handler.set_cookie("access_token",access_token)
        return access_token

class MessageHandler(tornado.web.RequestHandler):
    def get(self):
        msg_signature ,timestamp,echostr,nonce= self.get_arguments('msg_signature'),self.get_argument('timestamp'),self.get_argument('echostr'),self.get_argument('nonce')
        print "msg_signature=%s,timestamp=%s,echostr=%s,nonce=%s"%(msg_signature,timestamp,echostr,nonce)
        echostr = urllib.unquote(echostr)
        print "msg_signature=%s,timestamp=%s,echostr=%s,nonce=%s"%(msg_signature,timestamp,echostr,nonce)
        wxcpt = WXBizMsgCrypt(message_SToken,message_sEncodingAESKey,sCorpID)
        ret,sEchoStr = wxcpt.VerifyURL(msg_signature[0],timestamp,nonce,echostr)
        print 'ret=%s,sEchoStr is %s'%(ret,sEchoStr)
        self.write(sEchoStr)

    def post(self):
        sReqData = self.request.body
        msg_signature ,timestamp,nonce= self.get_arguments('msg_signature'),self.get_argument('timestamp'),self.get_argument('nonce')
        wxcpt = WXBizMsgCrypt(message_SToken,message_sEncodingAESKey,sCorpID)
        ret,sMsg = wxcpt.DecryptMsg(sReqData,msg_signature[0],timestamp,nonce)
        xml_tree = ET.fromstring(sMsg)
        print 'request xml is %s' % sMsg

        fromusername = xml_tree.find("FromUserName").text
        tousername = xml_tree.find("ToUserName").text
        msgtype = xml_tree.find("MsgType").text

        if msgtype == "text":
            text_content = xml_tree.find("Content").text
            self.responseText(wxcpt,nonce,timestamp,fromusername,tousername,msgtype,text_content)
        elif msgtype == "image":
            pic_url = xml_tree.find("PicUrl").text
            self.responseImage(wxcpt,nonce,timestamp,fromusername,tousername,"text","www.wedoapp.com")
        else :
             self.write("")

        def responseText(self,wxcpt,nonce,timestamp,tousername,fromusername,msgtype,cmd):
            content = ""
            if cmd == "list":
                content = "Very good, you have many policies"
            else:
                content = "If you input list cmd you will get more !"
            data = """<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[%s]]></MsgType> \ 
            <Content><![CDATA[%s]]></Content><MsgId>1234567890123456</MsgId><AgentID>128</AgentID></xml>"""%(fromusername,tousername,timestamp,msgtype,content)
            ret,sEncryptMsg=wxcpt.EncryptMsg(data, nonce, timestamp)
            self.write(sEncryptMsg)

    def responseText(self,wxcpt,nonce,timestamp,tousername,fromusername,msgtype,cmd):
        content = ""
        if cmd == "list":
            content = "Very good, you have many policies"
        else:
            content = "If you input list cmd you will get more !"
        data = """<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[%s]]></MsgType> \ 
        <Content><![CDATA[%s]]></Content><MsgId>1234567890123456</MsgId><AgentID>128</AgentID></xml>"""%(fromusername,tousername,timestamp,msgtype,content)
        ret,sEncryptMsg=wxcpt.EncryptMsg(data, nonce, timestamp)
        self.write(sEncryptMsg)
class PolicyMainHandler(tornado.web.RequestHandler):
    def get(self):
        msg_signature ,timestamp,echostr,nonce= self.get_arguments('msg_signature'),self.get_argument('timestamp'),self.get_argument('echostr'),self.get_argument('nonce')
        print "msg_signature=%s,timestamp=%s,echostr=%s,nonce=%s"%(msg_signature,timestamp,echostr,nonce)
        echostr = urllib.unquote(echostr)
        print "msg_signature=%s,timestamp=%s,echostr=%s,nonce=%s"%(msg_signature,timestamp,echostr,nonce)
        wxcpt = WXBizMsgCrypt(policy_SToken,policy_sEncodingAESKey,sCorpID)
        ret,sEchoStr = wxcpt.VerifyURL(msg_signature[0],timestamp,nonce,echostr)
        print 'ret=%s,sEchoStr is %s'%(ret,sEchoStr)
        self.write(sEchoStr)

    def post(self):
        print 'MainHandler post method called'
        sReqData = self.request.body
        msg_signature ,timestamp,nonce= self.get_arguments('msg_signature'),self.get_argument('timestamp'),self.get_argument('nonce')
        wxcpt = WXBizMsgCrypt(policy_SToken,policy_sEncodingAESKey,sCorpID)
        ret,sMsg = wxcpt.DecryptMsg(sReqData,msg_signature[0],timestamp,nonce)
        xml_tree = ET.fromstring(sMsg)
        print 'request xml is %s' % sMsg

        fromusername = xml_tree.find("FromUserName").text
        tousername = xml_tree.find("ToUserName").text
        msgtype = xml_tree.find("MsgType").text

        if msgtype == "text":
            text_content = xml_tree.find("Content").text
            self.responseText(wxcpt,nonce,timestamp,fromusername,tousername,msgtype,text_content)
        elif msgtype == "image":
            pic_url = xml_tree.find("PicUrl").text
            self.responseImage(wxcpt,nonce,timestamp,fromusername,tousername,"text","www.wedoapp.com")
        else :
            self.write("")

class PolicyCategoryHandler(tornado.web.RequestHandler):
    def get(self):
        uid = connect(odoo_common_url,odoo_db,odoo_user,odoo_pwd)
        sock = xmlrpclib.ServerProxy(odoo_object_url)
        categories = sock.execute(odoo_db,uid,odoo_pwd,'hr.reward.policy.category','search_read',[],['id','name','color'])
        print 'categories is %s' % categories
        self.render("templates/reward_category.html",categories=categories)

class PolicyListHandler(tornado.web.RequestHandler):
    def get(self):
        uid = connect(odoo_common_url,odoo_db,odoo_user,odoo_pwd)
        sock = xmlrpclib.ServerProxy(odoo_object_url)
        category_id = self.get_argument("category_id",0)
        print 'category_id is %s' % category_id
        policies = sock.execute(odoo_db,uid,odoo_pwd,'hr.reward.policy','search_read',[['category_id','=',int(category_id)]],['id','name'])
        print 'policies is %s' % policies
        self.render("templates/reward_policy_list.html",policies=policies)

class PolicyItemHandler(tornado.web.RequestHandler):
    def get(self):
        uid = connect(odoo_common_url,odoo_db,odoo_user,odoo_pwd)
        sock = xmlrpclib.ServerProxy(odoo_object_url)
        policy_id = self.get_argument("id",0)
        print 'policy_id is %s' % policy_id
        policy_items = sock.execute(odoo_db,uid,odoo_pwd,'hr.reward.policy.item','search_read',[['policy_id','=',int(policy_id)]],['id','content_type','content_text','content_binary'])
        print 'policy_items is %s' % policy_items
        self.render("templates/reward_policy.html",policy_items=policy_items)

class CityHandler(tornado.web.RequestHandler):
    def get(self):
        province_id = self.get_argument("province_id")
        print 'province_id is %s' % province_id
        uid = connect(odoo_common_url,odoo_db,odoo_user,odoo_pwd)
        sock = xmlrpclib.ServerProxy(odoo_object_url)
        locations = sock.execute(odoo_db,uid,odoo_pwd,'hr.social.location','search_read',[['state_id','=',int(province_id)]],['id','name'])
        print 'locations is %s' % locations
        locations = tornado.escape.json_encode(locations)
        self.write(locations)

class SocialHandler(tornado.web.RequestHandler):
    def get(self):
        uid = connect(odoo_common_url,odoo_db,odoo_user,odoo_pwd)
        sock = xmlrpclib.ServerProxy(odoo_object_url)
        item_types = sock.execute(odoo_db,uid,odoo_pwd,'hr.social.item.type','search_read',[],['id','name','short_name'])
        country_ids = sock.execute(odoo_db,uid,odoo_pwd,'res.country','search',[['code','=','CN']])
        provines = sock.execute(odoo_db,uid,odoo_pwd,'res.country.state','search_read',[['country_id','in',country_ids]],['id','name'])
        item_types.insert(0,{'id': 0, 'short_name': u'所有项目', 'name': u'所有项目'})
        print 'item_types is %s'%item_types
        self.render("templates/social_search.html",item_types=item_types,provines=provines)

    def post(self):
        #print self.request.body
        #print self.request.arguments
        province_id = self.get_argument('province',0)
        location_id = self.get_argument('city',0)
        socialtype = self.get_argument('socialtype',0)
        year = self.get_argument('year',0)
        uid = connect(odoo_common_url,odoo_db,odoo_user,odoo_pwd)
        sock = xmlrpclib.ServerProxy(odoo_object_url)

        domain = [['state_id','=',int(province_id)],['location_id','=',int(location_id)],['name','=',year]]
        socialtype = int(socialtype)
        if socialtype:
            domain.append(['item_type_id','=',int(socialtype)])

        items = sock.execute(odoo_db,uid,odoo_pwd,'hr.social','search_read',domain,[])
        #print items
        #print province_id,location_id,socialtype,year
        self.render("templates/social_search_result.html",items=items)

class DepartmentHandler(tornado.web.RequestHandler):
    def get(self):
        token = get_access_token(self)
        get_list_url ="https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=%s"
        res = requests.get(get_list_url%token)
        data = res.json()
        departments = data["department"]
        self.render("templates/departments.html",items=departments)

class WeixinAuthHandler(tornado.web.RequestHandler):
    def get(self):
        state,code = self.get_argument("state"),self.get_argument("code")
        #token = get_access_token(self)
        res = requests.get(GET_TOKEN_URL%(sCorpID,it_key))
        access_token = res.json()["access_token"]
        print 'token is %s' % access_token
        get_user_info_url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=%s&code=%s&agentid=%s"
        get_user_info_url = get_user_info_url %(access_token,code,0)
        user_info = requests.get(get_user_info_url).json()
        print "user_info is %s" % user_info
        return self.render("templates/register.html",code=code,state=state,openid=user_info["UserId"])

    def post(self):
        print 'request.body is %s' %  self.request.body
        username = self.get_argument("username")
        openid = self.get_argument("openid")
        password = self.get_argument("password")

        print username,openid,password
        item = {
            'username':username,
            'openid':openid,
            'password':password,
        }
        res_code = add_user(item)

        res = requests.get(GET_TOKEN_URL%(sCorpID,it_key))
        access_token = res.json()["access_token"]
        authsucc_url  = "https://qyapi.weixin.qq.com/cgi-bin/user/authsucc?access_token=%s&userid=%s"%(access_token,openid)
        res = requests.get(authsucc_url)
        print "res is %s" % res.json()
        self.render("templates/register_res.html",msg=ERROS[str(res_code)])

class WeatherHandler(tornado.web.RequestHandler):
    def get(self):
        msg_signature ,timestamp,echostr,nonce= self.get_arguments('msg_signature'),self.get_argument('timestamp'),self.get_argument('echostr'),self.get_argument('nonce')
        echostr = urllib.unquote(echostr)
        token = "VFPr2vH2OioFRkjaxM"
        aeskey = "2dqnNYe8Z7gXY1Nf1dcaoLdfULFKcq4AzHekVuorq5F"
        wxcpt = WXBizMsgCrypt(token,aeskey,sCorpID)
        ret,sEchoStr = wxcpt.VerifyURL(msg_signature[0],timestamp,nonce,echostr)
        self.write(sEchoStr)

    def post(self):
        print 'WeatherHandler post method called'
        sReqData = self.request.body
        sReqData = urllib.unquote(sReqData)
        sReqData = sReqData.decode("utf-8")
        print "sReqData is %s" % sReqData
        msg_signature ,timestamp,nonce= self.get_arguments('msg_signature'),self.get_argument('timestamp'),self.get_argument('nonce')
        print "msg_signature=%s,timestamp=%s,nonce=%s"%(msg_signature,timestamp,nonce)
        token = u"VFPr2vH2OioFRkjaxM"
        aeskey = u"2dqnNYe8Z7gXY1Nf1dcaoLdfULFKcq4AzHekVuorq5F"
        wxcpt = WXBizMsgCrypt(token,aeskey,sCorpID)
        ret,sMsg = wxcpt.DecryptMsg(sReqData,msg_signature[0],timestamp,nonce)        
        xml_tree = ET.fromstring(sMsg)
        print 'request xml is %s' % sMsg
        
        fromusername = xml_tree.find("FromUserName").text
        tousername = xml_tree.find("ToUserName").text
        msgtype = xml_tree.find("MsgType").text

        if msgtype=="text":
            city = xml_tree.find("Content").text
            self.get_city_weather(wxcpt,nonce,fromusername,tousername,timestamp,city)
        else: 
            self.write("")

    def get_city_weather(self,wxcpt,nonce,tousername,fromusername,timestamp,city):
        result = requests.get(WEATHER_URL%city)
        data = self.getNews(timestamp,tousername,fromusername,result.json())
        ret,sEncryptMsg=wxcpt.EncryptMsg(data, nonce, timestamp)
        print 'ret=%s,sEncryptMsg=%s'%(ret,sEncryptMsg)
        self.write(sEncryptMsg)


    def getNews(self,timestamp,tousername,fromusername,data):
        item_template = """
                <item>
                    <Title><![CDATA[%s]]></Title>
                    <Description><![CDATA[%s]]></Description>
                    <PicUrl><![CDATA[%s]]></PicUrl>
                    <Url><![CDATA[%s]]></Url>
                </item>"""
        items = []
        for line in data:
            items.append(item_template%(line["Title"],line["Description"],line["PicUrl"],line["Url"]))
        articles = """
                <xml>
                    <ToUserName><![CDATA[%s]]></ToUserName>
                    <FromUserName><![CDATA[%s]]></FromUserName>
                    <CreateTime>%s</CreateTime>
                    <MsgType><![CDATA[news]]></MsgType>
                    <Content><![CDATA[]]></Content>
                    <ArticleCount>%s</ArticleCount>
                    <Articles>%s</Articles>
                </xml>"""%(tousername,fromusername,timestamp,len(data),"".join(items))
        return articles

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        msg_signature ,timestamp,echostr,nonce= self.get_arguments('msg_signature'),self.get_argument('timestamp'),self.get_argument('echostr'),self.get_argument('nonce')
        print "msg_signature=%s,timestamp=%s,echostr=%s,nonce=%s"%(msg_signature,timestamp,echostr,nonce)
        echostr = urllib.unquote(echostr)
        print "msg_signature=%s,timestamp=%s,echostr=%s,nonce=%s"%(msg_signature,timestamp,echostr,nonce)
        wxcpt = WXBizMsgCrypt(SToken,sEncodingAESKey,sCorpID)
        ret,sEchoStr = wxcpt.VerifyURL(msg_signature[0],timestamp,nonce,echostr)
        print 'ret=%s,sEchoStr is %s'%(ret,sEchoStr)
        self.write(sEchoStr)

    def post(self):
        print 'MainHandler post method called'
        sReqData = self.request.body
        msg_signature ,timestamp,nonce= self.get_arguments('msg_signature'),self.get_argument('timestamp'),self.get_argument('nonce')
        wxcpt = WXBizMsgCrypt(SToken,sEncodingAESKey,sCorpID)
        ret,sMsg = wxcpt.DecryptMsg(sReqData,msg_signature[0],timestamp,nonce)        
        xml_tree = ET.fromstring(sMsg)
        print 'request xml is %s' % sMsg
        
        fromusername = xml_tree.find("FromUserName").text
        tousername = xml_tree.find("ToUserName").text
        msgtype = xml_tree.find("MsgType").text

        if msgtype == "text":
            text_content = xml_tree.find("Content").text
            self.responseText(wxcpt,nonce,timestamp,fromusername,tousername,msgtype,text_content)
        elif msgtype == "image":
            pic_url = xml_tree.find("PicUrl").text
            self.responseImage(wxcpt,nonce,timestamp,fromusername,tousername,"text","www.wedoapp.com")
        else :
            self.write("")
    
    def responseText(self,wxcpt,nonce,timestamp,tousername,fromusername,msgtype,cmd):
        content = ""
        if cmd == "list":
            content = "Very good, you have many policies"
        else:
            content = "If you input list cmd you will get more !"
        data = """<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[%s]]></MsgType> \ 
        <Content><![CDATA[%s]]></Content><MsgId>1234567890123456</MsgId><AgentID>128</AgentID></xml>"""%(fromusername,tousername,timestamp,msgtype,content)
        ret,sEncryptMsg=wxcpt.EncryptMsg(data, nonce, timestamp)
        self.write(sEncryptMsg)

    def responseImage(self,wxcpt,nonce,timestamp,tousername,fromusername,msgtype,url):
        url = urllib.quote(url)
        print 'pic url is %s' % url
        data = "<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[%s]]></MsgType><Content><![CDATA[%s]]></Content><MsgId>1234567890123456</MsgId><AgentID>128</AgentID></xml>"%(fromusername,tousername,timestamp,msgtype,url)
        print 'data is %s' % data
        ret,sEncryptMsg=wxcpt.EncryptMsg(data, nonce, timestamp)
        self.write(sEncryptMsg)

class HelloHandler(tornado.web.RequestHandler):
    def get(self):
        print 'HelloHandler called'
        print 'self is %s' % self
        print 'arguments is %s' % self.request.arguments
        msg_signature = self.get_arguments('msg_signature')
        print "msg_signature=%s"%(msg_signature)
        self.write("Hello baby!")


application = tornado.web.Application([
    (r"/",MainHandler),
    (r"/hello",HelloHandler),
    (r"/weather",WeatherHandler),
    (r"/register",WeixinAuthHandler),
    (r"/departments",DepartmentHandler),
    (r"/social",SocialHandler),
    (r"/city",CityHandler),
    (r"/policy",PolicyMainHandler),
    (r"/message",MessageHandler),
    (r"/policy/category",PolicyCategoryHandler),
    (r"/policy/list",PolicyListHandler),
    (r"/policy/item",PolicyItemHandler),
])

if __name__ == "__main__":
    application.listen(80)
    tornado.ioloop.IOLoop.instance().start()
